
package model.persistencia;

import java.sql.*;
import java.util.ArrayList;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JOptionPane;
import model.*;

public class ProdutoDAO implements IGenericDAO{  
    
    private Statement stmt;
    private Connection con;
    private PreparedStatement ps;
    private BancoDeDados conexaoBanco;
    private ResultSet resultado;
    private ICategoria categoria;
    private IFornecedor fornecedor;
    private IUnidade unidade;
    private ProdutoModel produto;
    
    public ProdutoDAO(ProdutoModel produto) {
        this.conexaoBanco = new BancoDeDados();         
        this.categoria = new CategoriaModel();
        this.fornecedor = new FornecedorModel();
        this.unidade = new UnidadeModel();
        this.produto = produto;
    }
   
    @Override
    public void inserir(){
        con = null;
        ps = null;            
        con = conexaoBanco.getConexao();              
        String comando = "INSERT INTO produto(produto_pk, unidade_fk, categoria_fk, fornecedor_fk, descricao, "
                    + "vlrcompra, vlrvenda, estoque, critico, auditoria) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?);";        
        try {     
            ps = con.prepareStatement(comando);            
            ps.setInt(1, produto.getCodigo());
            ps.setInt(2, produto.getUnidade().getCodigo());
            ps.setInt(3, produto.getCategoria().getCodigo());
            ps.setInt(4, produto.getFornecedor().getCodigo());
            ps.setString(5, produto.getDescricao());            
            ps.setDouble(6, produto.getValorCompra());
            ps.setDouble(7, produto.getValorVenda());
            ps.setInt(8, produto.getEstoque());
            ps.setInt(9, produto.getEstoqueCritico()); 
            ps.setString(10, produto.getAuditoria());
            ps.execute();                            
        } catch (SQLException ex) {
            Logger.getLogger(ProdutoDAO.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(null, "Erro no no banco no cadastro de Produto:\n"+
                        ex.getMessage()+"\n","Mensagem de Erro!",JOptionPane.ERROR_MESSAGE);
        }finally{
            try {
                ps.close();
                con.close();                
                stmt.close();
            } catch (SQLException ex) {
                Logger.getLogger(ProdutoDAO.class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(null, "Erro ao encerrar conexão:\n"+
                        ex.getMessage()+"\n","Mensagem de Erro!",JOptionPane.ERROR_MESSAGE);                
            }
                
        }
    }

    @Override
    public void excluir() {
        con = null;
        ps = null;
        con = conexaoBanco.getConexao(); 
        String sql = "DELETE FROM produto WHERE produto_pk = "+produto.getCodigo()+";";  
        try {
            ps = con.prepareStatement(sql);
            ps.execute();
        } catch (SQLException ex) {
            Logger.getLogger(ProdutoDAO.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(null, "Erro no banco no Exclusão de Produto:\n"+
                        ex.getMessage()+"\n","Mensagem de Erro!",JOptionPane.ERROR_MESSAGE);
        }finally{
            try {
                con.close();
                ps.close();
            } catch (SQLException ex) {
                Logger.getLogger(ProdutoDAO.class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(null, "Erro ao encerrar conexão:\n"+
                        ex.getMessage()+"\n","Mensagem de Erro!",JOptionPane.ERROR_MESSAGE);
            }           
        }
    }

    @Override
    public void atualizar() {
        con = null;
        ps = null;       
        con = conexaoBanco.getConexao();         
        String sql = "UPDATE produto SET unidade_fk=?, categoria_fk=?, fornecedor_fk=?, "
                + "descricao=?, vlrcompra=?, vlrvenda=?, estoque=?, critico=?, auditoria=? "
                + "WHERE produto_pk=?;";        
        try{
            ps = con.prepareStatement(sql);                        
            ps.setInt(1, produto.getUnidade().getCodigo());            
            ps.setInt(2, produto.getCategoria().getCodigo());
            ps.setInt(3, produto.getFornecedor().getCodigo());
            ps.setString(4, produto.getDescricao());
            ps.setDouble(5, produto.getValorCompra());
            ps.setDouble(6, produto.getValorVenda());
            ps.setInt(7, produto.getEstoque());
            ps.setInt(8, produto.getEstoqueCritico());
            ps.setString(9, produto.getAuditoria());
            ps.setInt(10, produto.getCodigo());            
            ps.executeUpdate();            
        }catch(SQLException ex) {
            Logger.getLogger(ProdutoDAO.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(null, "Erro ao execultar a Atualização de Produto:\n"+
                    ex.getMessage()+"\n","Mensagem de Erro!",JOptionPane.ERROR_MESSAGE);
        }finally{
            try {
                ps.close();
                con.close();                
            } catch (SQLException ex) {
                Logger.getLogger(ProdutoDAO.class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(null, "Erro ao encerrar conexão:\n"+
                        ex.getMessage()+"\n","Mensagem de Erro!",JOptionPane.ERROR_MESSAGE);
            }            
        }
    }

    @Override
    public ArrayList pesquisar(int iOpcao, String iPesquisa) {
        ArrayList listaProdutos = new ArrayList();        
        resultado = null;
        con = null;        
        stmt = null;                           
        con = conexaoBanco.getConexao();          
        try{        
            stmt = (Statement) con.createStatement();            
            resultado = stmt.executeQuery(getSQL(iOpcao, iPesquisa));                
            while(resultado.next()) {
                ProdutoModel produtoTemp = new ProdutoModel();            
                produtoTemp.setCodigo(resultado.getInt("produto_pk"));                
                produtoTemp.setDescricao(resultado.getString("descricao"));                
                produtoTemp.setCategoria(categoria.getCategoria(resultado.getInt("categoria_fk")));
                produtoTemp.setFornecedor(fornecedor.getFornecedor(resultado.getInt("fornecedor_fk")));
                produtoTemp.setUnidade(unidade.getUnidade(resultado.getInt("unidade_fk")));
                produtoTemp.setEstoque(resultado.getInt("estoque"));
                produtoTemp.setEstoqueCritico(resultado.getInt("critico"));                
                produtoTemp.setValorCompra(resultado.getDouble("vlrcompra"));
                produtoTemp.setValorVenda(resultado.getDouble("vlrvenda"));
                produtoTemp.setAuditoria(resultado.getString("auditoria"));                
                listaProdutos.add(produtoTemp);
            }
        } catch (SQLException ex) {
            Logger.getLogger(ProdutoDAO.class.getName()).log(Level.SEVERE, null, ex);            
            JOptionPane.showMessageDialog(null, "Erro na Pesquisa de Produtos.\n"+
                    ex.getMessage(),"Mensagem de Erro!",JOptionPane.ERROR_MESSAGE);
        }finally{
            try {
                con.close();
                stmt.close();
                resultado.close();
            } catch (SQLException ex) {
                Logger.getLogger(ProdutoDAO.class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(null, "Erro ao encerrar conexão:\n"+
                        ex.getMessage()+"\n","Mensagem de Erro!",JOptionPane.ERROR_MESSAGE);
            }
        }               
        return listaProdutos;
    }

    @Override
    public String getSQL(int iOpcao, String iPesquisa) {
        String sql = null;        
        switch (iOpcao){
            case IProduto.SQL_PRIMEIRO: sql = "SELECT MIN(produto.produto_pk) as produto_pk FROM public.produto;";break;
                
            case IProduto.SQL_ANTERIOR: sql = "SELECT MAX(produto.produto_pk) as produto_pk "
                    + "FROM public.produto WHERE produto.produto_pk < "+ iPesquisa +";";break;
                
            case IProduto.SQL_PROXIMO: sql = "SELECT MIN(produto.produto_pk) as produto_pk "
                    + "FROM public.produto WHERE produto.produto_pk > "+ iPesquisa +";";break;
                
            case IProduto.SQL_ULTIMO: sql = "SELECT MAX(produto.produto_pk) as produto_pk FROM public.produto;";break;
                
            case IProduto.SQL_CODIGO: sql = "SELECT produto.produto_pk, produto.unidade_fk, produto.categoria_fk, "
                    + "produto.fornecedor_fk, produto.descricao, produto.vlrcompra, produto.vlrvenda, "
                    + "produto.estoque, produto.critico, categoria.descricao as categoria, unidade.descricao as unidade, "
                    + "fornecedor.nome as fornecedor, produto.auditoria FROM public.categoria, public.fornecedor, public.produto, public.unidade "
                    + "WHERE produto.unidade_fk = unidade.unidade_pk AND produto.categoria_fk = categoria.categoria_pk AND "
                    + "produto.fornecedor_fk = fornecedor.fornecedor_pk AND produto.produto_pk = "+ iPesquisa +";";break;
                
            case IProduto.SQL_DESCRICAO: sql = "SELECT produto.produto_pk, produto.unidade_fk, produto.categoria_fk, produto.fornecedor_fk, "
                    + "produto.descricao, produto.vlrcompra, produto.vlrvenda, produto.estoque, produto.critico, "
                    + "categoria.descricao AS categoria, unidade.descricao AS unidade, fornecedor.nome AS fornecedor, produto.auditoria "
                    + "FROM public.categoria, public.fornecedor, public.produto, public.unidade "
                    + "WHERE produto.unidade_fk = unidade.unidade_pk AND produto.categoria_fk = categoria.categoria_pk AND "
                    + "produto.fornecedor_fk = fornecedor.fornecedor_pk AND produto.descricao like "
                    + "'%"+ iPesquisa +"%' ORDER BY produto.descricao LIMIT (50);";break;
                
            case IProduto.SQL_CATEGORIA: sql = "SELECT categoria.descricao as categoria, produto.produto_pk, produto.descricao, produto.vlrcompra, "
                    + "produto.vlrvenda, produto.estoque, produto.critico, fornecedor.nome as fornecedor, unidade.descricao as unidade, "
                    + "produto.categoria_fk, produto.fornecedor_fk, produto.unidade_fk, produto.auditoria "
                    + "FROM public.categoria, public.fornecedor, public.produto, public.unidade "
                    + "WHERE fornecedor.fornecedor_pk = produto.fornecedor_fk AND "
                    + "produto.unidade_fk = unidade.unidade_pk AND produto.categoria_fk = categoria.categoria_pk AND "
                    + "categoria.descricao like '%"+ iPesquisa +"';";break;    
            case IProduto.SQL_FORNECEDOR: sql = "SELECT categoria.descricao as categoria, produto.produto_pk, produto.descricao, produto.vlrcompra, "
                    + "produto.vlrvenda, produto.estoque, produto.critico, fornecedor.nome as fornecedor, unidade.descricao as unidade, "
                    + "produto.categoria_fk, produto.fornecedor_fk, produto.unidade_fk, produto.auditoria "
                    + "FROM public.categoria, public.fornecedor, public.produto, public.unidade "
                    + "WHERE fornecedor.fornecedor_pk = produto.fornecedor_fk AND "
                    + "produto.unidade_fk = unidade.unidade_pk AND produto.categoria_fk = categoria.categoria_pk AND "
                    + "fornecedor.nome like '%"+ iPesquisa +"';";break;                               
            case IProduto.SQL_GETALL: sql = "SELECT categoria.descricao as categoria, produto.produto_pk, produto.descricao, produto.vlrcompra, "
                    + "produto.vlrvenda, produto.estoque, produto.critico, fornecedor.nome as fornecedor, unidade.descricao as unidade, "
                    + "produto.categoria_fk, produto.fornecedor_fk, produto.unidade_fk, produto.auditoria "
                    + "FROM public.categoria, public.fornecedor, public.produto, public.unidade "
                    + "WHERE fornecedor.fornecedor_pk = produto.fornecedor_fk AND "
                    + "produto.unidade_fk = unidade.unidade_pk AND produto.categoria_fk = categoria.categoria_pk;";break;    
        }        
        return sql;
    }

    @Override
    public int getCodigo(int iOpcao, int iCodigoAtual) {
        stmt = null;
        resultado = null;
        con = null;        
        con = conexaoBanco.getConexao(); 
        int codigoEncontrado = -1;        
        try{        
            stmt = (Statement) con.createStatement();
            resultado = stmt.executeQuery(getSQL(iOpcao, String.valueOf(iCodigoAtual)));        
            resultado.next();
            codigoEncontrado = resultado.getInt("produto_pk");
        }catch(SQLException ex) {
            Logger.getLogger(ProdutoDAO.class.getName()).log(Level.SEVERE, null, ex);
            JOptionPane.showMessageDialog(null, "Erro ao execultar a sql de Pesquisa:\n"+
                    ex.getMessage()+"\n","Mensagem de Erro!",JOptionPane.ERROR_MESSAGE);
        }finally{
            try {
                con.close();
                stmt.close();
                resultado.close();
            } catch (SQLException ex) {
                Logger.getLogger(ProdutoDAO.class.getName()).log(Level.SEVERE, null, ex);
                JOptionPane.showMessageDialog(null, "Erro ao encerrar conexão:\n"+
                        ex.getMessage()+"\n","Mensagem de Erro!",JOptionPane.ERROR_MESSAGE);
            }            
        }        
        return codigoEncontrado;  
    }

    @Override
    public ProdutoModel getObject(int id) {
        ArrayList<ProdutoModel> listaProdutos;        
        listaProdutos = pesquisar(IProduto.SQL_CODIGO, String.valueOf(id));
        return listaProdutos.get(0);         
    }    
}
